package com.wrx.club_management_backend.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wrx.club_management_backend.common.AjaxResult;
import com.wrx.club_management_backend.dto.ApproveClubDTO;
import com.wrx.club_management_backend.entity.Club;
import com.wrx.club_management_backend.mapper.ClubMapper;
import com.wrx.club_management_backend.service.ClubService;
import com.wrx.club_management_backend.utils.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.wrx.club_management_backend.utils.RedisConstant.*;

@Slf4j
@Service
public class ClubServiceImpl extends ServiceImpl<ClubMapper, Club> implements ClubService {
    @Autowired
    private ClubMapper clubMapper;

    @Autowired
    StringRedisTemplate stringRedisTemplate;


    @Override
    public AjaxResult getClubDetail(Long id) {
        String s = stringRedisTemplate.opsForValue().get(CACHE_CLUB + id);
        if ("".equals(s)) {
            return AjaxResult.success("不存在该社团");
        } else {
            Club club = this.getById(id);
            if(club == null){
                stringRedisTemplate.opsForValue().set(CACHE_CLUB + id, "", CACHE_TTL, TimeUnit.MINUTES);
                return AjaxResult.success("不存在该社团");
            }
            Map<String, Object> map = BeanUtil.beanToMap(club);
            stringRedisTemplate.opsForValue().set(CACHE_CLUB + id,map.toString()); // 将对象转为map再转为string存储到redis中
            return AjaxResult.success(club);
        }
    }

    @Override
    public AjaxResult getClubActivities(Long clubId) {
        try {
            List<Map<String, Object>> activities = clubMapper.selectClubActivities(clubId);
            return AjaxResult.success(activities);
        } catch (Exception e) {
            log.error("查询社团活动列表时出现异常", e);
            return AjaxResult.error("查询社团活动列表时出现异常");
        }
    }

    @Override
    public AjaxResult getClubMembers(Long clubId) {
        try {
            List<Map<String, Object>> members = clubMapper.selectClubMembers(clubId);
            return AjaxResult.success(members);
        } catch (Exception e) {
            log.error("查询社团成员列表时出现异常", e);
            return AjaxResult.error("查询社团成员列表时出现异常");
        }
    }

    @Override
    public AjaxResult getClubAchievements(Long clubId) {
        try {
            List<Map<String, Object>> achievements = clubMapper.selectClubAchievements(clubId);
            return AjaxResult.success(achievements);
        } catch (Exception e) {
            log.error("查询社团荣誉列表时出现异常", e);
            return AjaxResult.error("查询社团荣誉列表时出现异常");
        }
    }

    @Override
    @Transactional
    public AjaxResult updateFavorite(Long clubId, Long userId, Boolean isFavorite) {
        try {
            int count = clubMapper.checkFavorite(clubId, userId);
            if (isFavorite && count == 0) {
                // 添加收藏
                clubMapper.insertFavorite(clubId, userId);
            } else if (!isFavorite && count > 0) {
                // 取消收藏
                clubMapper.deleteFavorite(clubId, userId);
            }
            return AjaxResult.success("操作成功");
        } catch (Exception e) {
            log.error("更新收藏状态时出现异常", e);
            return AjaxResult.error("更新收藏状态时出现异常");
        }
    }

    @Override
    @Transactional
    public AjaxResult signupActivity(Long activityId, Long userId) {
        try {
            // 检查是否已报名
            int count = clubMapper.checkActivitySignup(activityId, userId);
            if (count > 0) {
                return AjaxResult.error("您已报名该活动");
            }

            // 添加报名记录
            clubMapper.insertActivitySignup(activityId, userId);
            return AjaxResult.success("报名成功");
        } catch (Exception e) {
            log.error("活动报名时出现异常", e);
            return AjaxResult.error("活动报名时出现异常");
        }
    }

    @Override
    @Transactional
    public AjaxResult joinClub(Long clubId, Long userId) {
        try {
            // 检查是否已是社团成员
            int count = clubMapper.checkClubMember(clubId, userId);
            if (count > 0) {
                return AjaxResult.error("您已是该社团成员");
            }

            // 添加社团成员记录
            clubMapper.insertClubMember(clubId, userId);
            return AjaxResult.success("加入社团成功");
        } catch (Exception e) {
            log.error("加入社团时出现异常", e);
            return AjaxResult.error("加入社团时出现异常");
        }
    }

    @Override
    @Transactional
    public AjaxResult quitClub(Long clubId, Long userId) {
        try {
            // 检查是否是社团成员
            int count = clubMapper.checkClubMember(clubId, userId);
            if (count == 0) {
                return AjaxResult.error("您不是该社团成员");
            }

            // 更新社团成员状态为退出(0)
            clubMapper.updateClubMemberStatus(clubId, userId, 0);
            return AjaxResult.success("退出社团成功");
        } catch (Exception e) {
            log.error("退出社团时出现异常", e);
            return AjaxResult.error("退出社团时出现异常");
        }
    }

    @Override
    @Transactional
    public AjaxResult appointManager(Long clubId, Long userId, String position, String department) {
        try {
            // 检查是否是社团成员
            int count = clubMapper.checkClubMember(clubId, userId);
            if (count == 0) {
                return AjaxResult.error("该用户不是社团成员");
            }

            // 添加管理层记录
            Map<String, Object> params = new HashMap<>();
            params.put("clubId", clubId);
            params.put("userId", userId);
            params.put("position", position);
            params.put("department", department);
            clubMapper.insertManager(params);

            return AjaxResult.success("任命管理层成功");
        } catch (Exception e) {
            log.error("任命管理层时出现异常", e);
            return AjaxResult.error("任命管理层时出现异常");
        }
    }

    @Override
    @Transactional
    public AjaxResult dismissManager(Long clubId, Long userId, String position) {
        try {
            // 更新管理层状态为解除(0)
            Map<String, Object> params = new HashMap<>();
            params.put("clubId", clubId);
            params.put("userId", userId);
            params.put("position", position);
            clubMapper.updateManagerStatus(params);

            return AjaxResult.success("解除管理层职务成功");
        } catch (Exception e) {
            log.error("解除管理层职务时出现异常", e);
            return AjaxResult.error("解除管理层职务时出现异常");
        }
    }

    @Override
    public AjaxResult getClubPresident(Long clubId) {
        try {
            // 查询部长信息
            Map<String, Object> president = clubMapper.selectClubPresident(clubId);
            if (president != null) {
                return AjaxResult.success(president);
            }
            return AjaxResult.success(null);
        } catch (Exception e) {
            log.error("查询社团部长信息时出现异常", e);
            return AjaxResult.error("查询社团部长信息时出现异常");
        }
    }

    @Override
    public AjaxResult getManagedClubs(Long userId) {
        try {
            List<Map<String, Object>> managedClubs = clubMapper.selectManagedClubs(userId);

            // 获取每个社团的额外统计信息
            managedClubs.forEach(club -> {
                Long clubId = (Long) club.get("id");

                // 获取成员数量
                int memberCount = clubMapper.checkClubMember(clubId, null);
                club.put("memberCount", memberCount);

                // 获取活动数量（需要添加相应的mapper方法）
                List<Map<String, Object>> activities = clubMapper.selectClubActivities(clubId);
                club.put("activityCount", activities.size());

                // 获取荣誉数量
                List<Map<String, Object>> achievements = clubMapper.selectClubAchievements(clubId);
                club.put("achievementCount", achievements.size());
            });

            return AjaxResult.success(managedClubs);
        } catch (Exception e) {
            log.error("获取用户管理的社团列表时出现异常", e);
            return AjaxResult.error("获取社团列表失败");
        }
    }

    /**
     * 获取当前用户参加的社团
     *
     * @return
     */
    @Override
    public AjaxResult get() {
        Long userId = UserHolder.getUser().getId();
        List<Club> list = clubMapper.getClubByUserId(userId);
        list = list.stream().filter(item -> item.getStat() == 1).collect(Collectors.toList()); // 把stat 不为1的过滤掉
        return AjaxResult.success(list);
    }

    /**
     * 收藏社团
     *
     * @param clubId
     * @return
     */
    @Override
    public AjaxResult collected(Long clubId) {
        Long userId = UserHolder.getUser().getId();
        // 判断用户是否收藏了该社团，如果没有收藏，就直接收藏
        String useId = userId.toString();
        String key1 = CLUB_COLLECTION_KEY + clubId;
        String key2 = USER_CLUB_COLLECTION_KEY + userId;
        String clubId_str = clubId.toString(); // 社团id
        if (Boolean.FALSE.equals(stringRedisTemplate.opsForSet()
                .isMember(key1, useId))) {
            stringRedisTemplate.opsForSet().add(key1, useId); // 社团id ==》【用户id】
            stringRedisTemplate.opsForSet().add(key2, clubId_str); // 用户id ==》 【社团id】
        } else { // 如果收藏了，就直接取消收藏
            stringRedisTemplate.opsForSet().remove(key1, useId);
            stringRedisTemplate.opsForSet().remove(key2, clubId_str);
        }
        return AjaxResult.success("收藏成功");
    }

    @Override
    public AjaxResult updateStat(Long clubId, int recruit) {
        this.update(
                new LambdaUpdateWrapper<Club>()
                        .eq(Club::getId, clubId)
                        .set(Club::getRecruit, recruit)
        );
        return AjaxResult.success("状态修改成功");
    }

    /**
     * 用户是或否已经收藏该社团
     *
     * @param clubId
     * @return
     */
    @Override
    public AjaxResult isCollected(Long clubId) {
        Long userId = UserHolder.getUser().getId();
        Boolean flag = stringRedisTemplate.opsForSet().isMember(CLUB_COLLECTION_KEY + clubId, userId.toString());
        return AjaxResult.success(flag);
    }

    /**
     * 返回 clubId 社团的收藏数量
     *
     * @param clubId 社团id
     * @return
     */
    @Override
    public AjaxResult collectedNum(Long clubId) {
        Long size = stringRedisTemplate.opsForSet().size(CLUB_COLLECTION_KEY + clubId);
        return AjaxResult.success(size);
    }

    @Override
    public AjaxResult hot() {
        //1. 获取所有社团的ids
        List<Club> list = this.list(
                new LambdaQueryWrapper<Club>()
                        .eq(Club::getStat, 1)
        );
        for (Club club : list) {
            Long size = stringRedisTemplate.opsForSet().size(CLUB_COLLECTION_KEY + club.getId());
            size = size == null ? 0 : size;
            club.setCollectionNum(size);
        }
        //4. 返回数据
        return AjaxResult.success(list);
    }

    /**
     * 从社团中剔除 userid 的用户
     *
     * @param userId
     * @param clubId
     */
    @Override
    public void removeUser(Long userId, Long clubId) {
        clubMapper.removeUser(userId, clubId);
    }

    @Override
    public AjaxResult num() {
        int size = this.list().size();
        return AjaxResult.success(size);
    }

    /**
     * 创建社团方法
     *
     * @param club
     * @return
     */
    @Override
    @Transactional /*开启事物*/
    public AjaxResult create(Club club) {
        // 也要创建一个负责人记录
        Long userId = UserHolder.getUser().getId();
        club.setStat(0); // 社团待审核状态
        club.setEstablishDate(new Date());
        this.save(club); // 保存社团
        clubMapper.createManager(userId, club.getId()); // 创建一条管理者记录
        clubMapper.createUserClubLink(userId, club.getId());  // 添加一条user_club_link记录
        return null;
    }

    @Override
    public AjaxResult getApproveList() {
        List<Club> list = this.list(
                new LambdaQueryWrapper<Club>()
                        .eq(Club::getStat, 0)
        );
        return AjaxResult.success(list);
    }

    // 审批社团
    @Override
    public AjaxResult approve(ApproveClubDTO dto) {
        boolean flag = this.update(
                new LambdaUpdateWrapper<Club>()
                        .eq(dto.getClubId() != null, Club::getId, dto.getClubId())
                        .set(dto.getStat() != null, Club::getStat, dto.getStat())
                        .set(dto.getRemark() != null && !dto.getRemark().isEmpty(), Club::getRemark, dto.getRemark())

        );
        return AjaxResult.success("审批成功");
    }


    @Override
    public AjaxResult search(ApproveClubDTO dto) {
        List<Club> list = this.list(
                new LambdaQueryWrapper<Club>()
                        .like(dto.getTitle() != null && !dto.getTitle().isEmpty(), Club::getTitle, dto.getTitle())
                        .like(dto.getTags() != null, Club::getTags, dto.getTags())
                        .eq(dto.getStat() != null, Club::getStat, dto.getStat())
        );
        return AjaxResult.success(list);
    }
}
